package com.qinyu.treehole.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qinyu.treehole.bo.CommentBo;
import com.qinyu.treehole.entities.Comment;
import com.qinyu.treehole.entities.User;
import com.qinyu.treehole.mapper.CommentMapper;
import com.qinyu.treehole.service.CommentService;
import com.qinyu.treehole.service.UserService;
import com.qinyu.treehole.tool.CommentTool;
import com.qinyu.treehole.vo.FeedCommentVo;
import com.qinyu.treehole.vo.LoginFeedCommentVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Autowired
    private RedisTemplate jsonRedisTemplate;
    @Autowired
    private UserService userService;

    @Override
    public boolean saveComment(CommentBo commentBo) {
        Comment ct = new Comment();
        ct.setUserId(commentBo.getUserId());
        ct.setFeedId(commentBo.getFeedId());
        ct.setContent(commentBo.getContent());

        return save(ct);
    }

    @Override
    public void addLike(Integer userId, Integer commentId) {
        SetOperations<String, Integer> ops = jsonRedisTemplate.opsForSet();
        ops.add(CommentTool.COMMENT_NAME+commentId, userId);
    }

    @Override
    public void removeLike(Integer userId, Integer commentId) {
        SetOperations<String, Integer> ops = jsonRedisTemplate.opsForSet();
        ops.remove(CommentTool.COMMENT_NAME+commentId, userId);
    }

    @Override
    public List<LoginFeedCommentVo> getLoginCommentsVoByFeedId(Integer feedId, Integer userId) {
        SetOperations<String, Integer> ops = jsonRedisTemplate.opsForSet();

        return list(new QueryWrapper<Comment>().eq("feed_id", feedId).orderByDesc("create_time"))
                .stream().map(ct->{
                    LoginFeedCommentVo vo = new LoginFeedCommentVo();

                    User user = userService.getById(ct.getUserId());
                    if(user == null) return null;
                    vo.setCommentId(ct.getId());
                    vo.setUserId(ct.getUserId());
                    vo.setUname(user.getName());
                    vo.setAvatar(user.getAvatar());
                    vo.setContent(ct.getContent());
                    vo.setCreateTime(ct.getCreateTime());

                    vo.setIsLike(ops.isMember(CommentTool.COMMENT_NAME+ct.getId(), userId));
                    vo.setLikeCount(ops.size(CommentTool.COMMENT_NAME+ct.getId()));

                    return vo;
                }).filter(obj->obj != null).collect(Collectors.toList());
    }

    @Override
    public List<FeedCommentVo> getCommentsVoByFeedId(Integer feedId) {
        SetOperations<String, Integer> ops = jsonRedisTemplate.opsForSet();

        return list(new QueryWrapper<Comment>().eq("feed_id", feedId).orderByDesc("create_time"))
                .stream().map(ct->{
                    FeedCommentVo vo = new FeedCommentVo();

                    User user = userService.getById(ct.getUserId());
                    if(user == null) return null;

                    vo.setCommentId(ct.getId());
                    vo.setUserId(ct.getUserId());
                    vo.setUname(user.getName());
                    vo.setAvatar(user.getAvatar());
                    vo.setContent(ct.getContent());
                    vo.setCreateTime(ct.getCreateTime());

                    vo.setLikeCount(ops.size(CommentTool.COMMENT_NAME+ct.getId()));
                    return vo;
                }).filter(obj->obj != null).collect(Collectors.toList());
    }

    @Override
    public long getCommentCountByFeedId(Integer feedId) {
        return count(new QueryWrapper<Comment>().eq("feed_id", feedId));
    }

    @Override
    public boolean isCommentFeedByUserId(Integer feedId, Integer userId) {
        return count(new QueryWrapper<Comment>().and(i->i.eq("user_id", userId).eq("feed_id", feedId))) > 0;
    }
}
